package day09.test2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class Ticket3 {
    private int num;
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition=lock.newCondition();

    public Ticket3() {
        this.num = 200;
    }

    public int getNum() {
        return num;
    }

    public void sellTicket() {
        lock.lock();
        try {
            while(this.num<0){
                try{
                    condition.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            /*
            * 如果使用if来判断条件（if (this.num <= 0)），当一个线程因为num <= 0而进入等待状态（await），假设它被唤醒后，它不会再次检查条件，而是直接继续执行后续代码（进行售票操作）。
这种方式可能会导致问题。例如，如果有多个线程在等待，当一个线程被唤醒后，它可能没有正确地感知到当前num的实际情况（可能其他线程已经修改了num的值），从而导致错误的操作（比如在没有票的情况下进行售票操作）。
            * */
            if (this.num > 0) {
                this.num--;
                System.out.println("现在是" + Thread.currentThread().getName() + "正在售票,还剩" + this.num + "张");
                condition.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }

}

public class test_ReentrantLoack_Object {
    public static void main(String[] args) {
        Ticket3 ticket=new Ticket3();

        Thread thread1=new Thread(()->{
            while(true){
                ticket.sellTicket();
                if(ticket.getNum()<=0){
                    break;
                }
            }
        },"售票线程1");

        Thread thread2=new Thread(()->{
            while(true){
                ticket.sellTicket();
                if(ticket.getNum()<=0){
                    break;
                }
            }
        },"售票线程2");

        Thread thread3=new Thread(()->{
            while(true){
                ticket.sellTicket();
                if(ticket.getNum()<=0){
                    break;
                }
            }
        },"售票线程3");

        thread1.start();
        thread2.start();
        thread3.start();

    }
}
